package com.maycur.ctrip.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.maycur.ctrip.domain.FeeData;
import com.maycur.ctrip.domain.FeeDynamicField;
import com.maycur.ctrip.enumeration.FeeDynamicFieldCode;
import com.maycur.ctrip.enumeration.FeeSourceType;
import com.maycur.ctrip.enumeration.FeeTypeGroupTag;
import com.maycur.ctrip.enumeration.PayType;
import com.maycur.ctrip.util.Constant;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by JoeyXin on 6/30/16.
 * 航班信息
 */
public class FlightTicketInfo {
    //航程
    @JsonProperty(value = "Sequence")
    private Integer sequence;

    //航班号
    @JsonProperty(value = "Flight")
    private String flightNo;

    //航空公司代码
    @JsonProperty(value = "AirLineCode")
    private String airLineCode;

    //航空公司名称
    @JsonProperty(value = "AirLineName")
    private String airLineName;

    //协议类型
    @JsonProperty(value = "Agreement")
    private String agreement;

    //机票价格+燃油+机场建设费
    @JsonProperty(value = "Amount")
    private BigDecimal totalAmount;

    //机票价格
    @JsonProperty(value = "Price")
    private BigDecimal ticketAmount;

    //机票票面价格/航空公司卖价
    @JsonProperty(value = "PrintPrice")
    private BigDecimal originalTicketAmount;

    //机票折扣:国内航班包含该字段,国际航班不包含。
    @JsonProperty(value = "PriceRate")
    private BigDecimal discount;

    //燃油费
    @JsonProperty(value = "OilFee")
    private BigDecimal oilAmount;

    //税/机场建设费
    @JsonProperty(value = "Tax")
    private BigDecimal taxAmount;

    //套餐强绑销售模式:S:服务费 I:保险费 U:优惠券
    @JsonProperty(value = "BindType")
    private String bindType;

    //优惠券数量: 当 BindType=“U”时, 该字段表示优惠券数量
    @JsonProperty(value = "BindNum")
    private Integer bindCount;

    //套餐强绑销售金额:固定金额,由 BindType类型决定
    @JsonProperty(value = "BindAmount")
    private BigDecimal bindAmount;

    //服务费
    @JsonProperty(value = "ServerFee")
    private BigDecimal serviceAmount;

    //飞享金
    @JsonProperty(value = "Subsidy")
    private BigDecimal subsidyAmount;

    //乘客种类(ADU=成人; CHI=儿童; BAB=婴儿)
    @JsonProperty(value = "AgeType")
    private String passengerType;

    //舱位名称
    @JsonProperty(value = "ClassName")
    private String className;

    //子舱位名称
    @JsonProperty(value = "SubClass")
    private String subClassName;

    //票台号
    @JsonProperty(value = "OfficeNo")
    private String officeNo;

    //是否可以改期,如:"不可改期"
    @JsonProperty(value = "NonRer")
    private String changeable;

    //改期规定, 如"不得更改"
    @JsonProperty(value = "RerNotes")
    private String changeNotes;

    //是否可以退票: 如:"不可退票"
    @JsonProperty(value = "NonRef")
    private String refundable;

    //退票规定: 如:"不得退票"
    @JsonProperty(value = "RefNotes")
    private String refundNotes;

    //是否可以改签,如:"不可签转"
    @JsonProperty(value = "NonEnd")
    private String endorsable;

    //改签规定
    @JsonProperty(value = "EndNotes")
    private String endorseNotes;

    //退改签备注信息
    @JsonProperty(value = "Remark")
    private String remark;

    //起飞时间
    @JsonProperty(value = "TakeoffTime")
    private Date takeOffAt;

    //到达时间
    @JsonProperty(value = "ArrivalTime")
    private Date arrivalAt;

    //出发城市名称
    @JsonProperty(value = "DCityName")
    private String departureCityName;

    //出发城市名称EN
    @JsonProperty(value = "DCityName_EN")
    private String departureCityNameEN;

    //出发城市编码: 3字符
    @JsonProperty(value = "DCityCode")
    private String departureCityCode;

    //出发机场名称
    @JsonProperty(value = "DPortName")
    private String departurePortName;

    //出发机场编码:3 字符
    @JsonProperty(value = "DPortCode")
    private String departurePortCode;

    //到达城市名称
    @JsonProperty(value = "ACityName")
    private String arrivalCityName;

    //到达城市名称EN
    @JsonProperty(value = "ACityName_EN")
    private String arrivalCityNameEN;

    //到达城市编码: 3字符
    @JsonProperty(value = "ACityCode")
    private String arrivalCityCode;

    //到达机场名称
    @JsonProperty(value = "APortName")
    private String arrivalPortName;

    //到达机场编码:3 字符
    @JsonProperty(value = "APortCode")
    private String arrivalPortCode;

    //是否open程: T:是,F:不是 Open 程含义:出发的航班跟时间都是确定的, 但返回的航班跟时间不确定
    @JsonProperty(value = "IsOpenTran")
    private String isOpenTran;

    //是否地面程: T:是,F:不是 地面程举例:北京到上海浦东,上海虹桥到北京 上海浦东,上海虹桥这两者之间有个地面程
    @JsonProperty(value = "IsSurface")
    private String isSurface;

    //低价规则代码
    @JsonProperty(value = "Reason")
    private String reason;

    //低价规则代码描述
    @JsonProperty(value = "ReasonDesc")
    private String reasonDesc;

    //提前预定规则代码
    @JsonProperty(value = "PreBookReason")
    private String preBookReason;

    //提前预定规则代码描述
    @JsonProperty(value = "PreBookReasonDesc")
    private String preBookReasonDesc;

    //最低价航班号
    @JsonProperty(value = "LowFlight")
    private String lowestFlightNo;

    //最低价航班舱位
    @JsonProperty(value = "LowClass")
    private String lowestClass;

    //最低价航班价格
    @JsonProperty(value = "LowestPrice")
    private BigDecimal lowestPrice;

    //最低价航班折扣率
    @JsonProperty(value = "LowRate")
    private BigDecimal lowestDiscount;

    //最低价航班起飞时间
    @JsonProperty(value = "LowDTime")
    private Date lowestDepartureAt;

    //最晚出票时间
    @JsonProperty(value = "Adtk")
    private Date adtk;

    //里程数
    @JsonProperty(value = "Tpm")
    private Integer tpm;

    //标准价:国内航班包含该字段,国际航班不包含。
    @JsonProperty(value = "StandardPrice")
    private BigDecimal standardAmount;

    public Integer getSequence() {
        return sequence;
    }

    public void setSequence(Integer sequence) {
        this.sequence = sequence;
    }

    public String getFlightNo() {
        return flightNo;
    }

    public void setFlightNo(String flightNo) {
        this.flightNo = flightNo;
    }

    public String getAirLineCode() {
        return airLineCode;
    }

    public void setAirLineCode(String airLineCode) {
        this.airLineCode = airLineCode;
    }

    public String getAirLineName() {
        return airLineName;
    }

    public void setAirLineName(String airLineName) {
        this.airLineName = airLineName;
    }

    public String getAgreement() {
        return agreement;
    }

    public void setAgreement(String agreement) {
        this.agreement = agreement;
    }

    public BigDecimal getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(BigDecimal totalAmount) {
        this.totalAmount = totalAmount;
    }

    public BigDecimal getTicketAmount() {
        return ticketAmount;
    }

    public void setTicketAmount(BigDecimal ticketAmount) {
        this.ticketAmount = ticketAmount;
    }

    public BigDecimal getOriginalTicketAmount() {
        return originalTicketAmount;
    }

    public void setOriginalTicketAmount(BigDecimal originalTicketAmount) {
        this.originalTicketAmount = originalTicketAmount;
    }

    public BigDecimal getDiscount() {
        return discount;
    }

    public void setDiscount(BigDecimal discount) {
        this.discount = discount;
    }

    public BigDecimal getOilAmount() {
        return oilAmount;
    }

    public void setOilAmount(BigDecimal oilAmount) {
        this.oilAmount = oilAmount;
    }

    public BigDecimal getTaxAmount() {
        return taxAmount;
    }

    public void setTaxAmount(BigDecimal taxAmount) {
        this.taxAmount = taxAmount;
    }

    public String getBindType() {
        return bindType;
    }

    public void setBindType(String bindType) {
        this.bindType = bindType;
    }

    public Integer getBindCount() {
        return bindCount;
    }

    public void setBindCount(Integer bindCount) {
        this.bindCount = bindCount;
    }

    public BigDecimal getBindAmount() {
        return bindAmount;
    }

    public void setBindAmount(BigDecimal bindAmount) {
        this.bindAmount = bindAmount;
    }

    public BigDecimal getServiceAmount() {
        return serviceAmount;
    }

    public void setServiceAmount(BigDecimal serviceAmount) {
        this.serviceAmount = serviceAmount;
    }

    public BigDecimal getSubsidyAmount() {
        return subsidyAmount;
    }

    public void setSubsidyAmount(BigDecimal subsidyAmount) {
        this.subsidyAmount = subsidyAmount;
    }

    public String getPassengerType() {
        return passengerType;
    }

    public void setPassengerType(String passengerType) {
        this.passengerType = passengerType;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getSubClassName() {
        return subClassName;
    }

    public void setSubClassName(String subClassName) {
        this.subClassName = subClassName;
    }

    public String getOfficeNo() {
        return officeNo;
    }

    public void setOfficeNo(String officeNo) {
        this.officeNo = officeNo;
    }

    public String getChangeable() {
        return changeable;
    }

    public void setChangeable(String changeable) {
        this.changeable = changeable;
    }

    public String getChangeNotes() {
        return changeNotes;
    }

    public void setChangeNotes(String changeNotes) {
        this.changeNotes = changeNotes;
    }

    public String getRefundable() {
        return refundable;
    }

    public void setRefundable(String refundable) {
        this.refundable = refundable;
    }

    public String getRefundNotes() {
        return refundNotes;
    }

    public void setRefundNotes(String refundNotes) {
        this.refundNotes = refundNotes;
    }

    public String getEndorsable() {
        return endorsable;
    }

    public void setEndorsable(String endorsable) {
        this.endorsable = endorsable;
    }

    public String getEndorseNotes() {
        return endorseNotes;
    }

    public void setEndorseNotes(String endorseNotes) {
        this.endorseNotes = endorseNotes;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Date getTakeOffAt() {
        return takeOffAt;
    }

    public void setTakeOffAt(Date takeOffAt) {
        this.takeOffAt = takeOffAt;
    }

    public Date getArrivalAt() {
        return arrivalAt;
    }

    public void setArrivalAt(Date arrivalAt) {
        this.arrivalAt = arrivalAt;
    }

    public String getDepartureCityName() {
        return departureCityName;
    }

    public void setDepartureCityName(String departureCityName) {
        this.departureCityName = departureCityName;
    }

    public String getDepartureCityNameEN() {
        return departureCityNameEN;
    }

    public void setDepartureCityNameEN(String departureCityNameEN) {
        this.departureCityNameEN = departureCityNameEN;
    }

    public String getDepartureCityCode() {
        return departureCityCode;
    }

    public void setDepartureCityCode(String departureCityCode) {
        this.departureCityCode = departureCityCode;
    }

    public String getDeparturePortName() {
        return departurePortName;
    }

    public void setDeparturePortName(String departurePortName) {
        this.departurePortName = departurePortName;
    }

    public String getDeparturePortCode() {
        return departurePortCode;
    }

    public void setDeparturePortCode(String departurePortCode) {
        this.departurePortCode = departurePortCode;
    }

    public String getArrivalCityName() {
        return arrivalCityName;
    }

    public void setArrivalCityName(String arrivalCityName) {
        this.arrivalCityName = arrivalCityName;
    }

    public String getArrivalCityNameEN() {
        return arrivalCityNameEN;
    }

    public void setArrivalCityNameEN(String arrivalCityNameEN) {
        this.arrivalCityNameEN = arrivalCityNameEN;
    }

    public String getArrivalCityCode() {
        return arrivalCityCode;
    }

    public void setArrivalCityCode(String arrivalCityCode) {
        this.arrivalCityCode = arrivalCityCode;
    }

    public String getArrivalPortName() {
        return arrivalPortName;
    }

    public void setArrivalPortName(String arrivalPortName) {
        this.arrivalPortName = arrivalPortName;
    }

    public String getArrivalPortCode() {
        return arrivalPortCode;
    }

    public void setArrivalPortCode(String arrivalPortCode) {
        this.arrivalPortCode = arrivalPortCode;
    }

    public String getIsOpenTran() {
        return isOpenTran;
    }

    public void setIsOpenTran(String isOpenTran) {
        this.isOpenTran = isOpenTran;
    }

    public String getIsSurface() {
        return isSurface;
    }

    public void setIsSurface(String isSurface) {
        this.isSurface = isSurface;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public String getReasonDesc() {
        return reasonDesc;
    }

    public void setReasonDesc(String reasonDesc) {
        this.reasonDesc = reasonDesc;
    }

    public String getPreBookReason() {
        return preBookReason;
    }

    public void setPreBookReason(String preBookReason) {
        this.preBookReason = preBookReason;
    }

    public String getPreBookReasonDesc() {
        return preBookReasonDesc;
    }

    public void setPreBookReasonDesc(String preBookReasonDesc) {
        this.preBookReasonDesc = preBookReasonDesc;
    }

    public String getLowestFlightNo() {
        return lowestFlightNo;
    }

    public void setLowestFlightNo(String lowestFlightNo) {
        this.lowestFlightNo = lowestFlightNo;
    }

    public String getLowestClass() {
        return lowestClass;
    }

    public void setLowestClass(String lowestClass) {
        this.lowestClass = lowestClass;
    }

    public BigDecimal getLowestPrice() {
        return lowestPrice;
    }

    public void setLowestPrice(BigDecimal lowestPrice) {
        this.lowestPrice = lowestPrice;
    }

    public BigDecimal getLowestDiscount() {
        return lowestDiscount;
    }

    public void setLowestDiscount(BigDecimal lowestDiscount) {
        this.lowestDiscount = lowestDiscount;
    }

    public Date getLowestDepartureAt() {
        return lowestDepartureAt;
    }

    public void setLowestDepartureAt(Date lowestDepartureAt) {
        this.lowestDepartureAt = lowestDepartureAt;
    }

    public Date getAdtk() {
        return adtk;
    }

    public void setAdtk(Date adtk) {
        this.adtk = adtk;
    }

    public Integer getTpm() {
        return tpm;
    }

    public void setTpm(Integer tpm) {
        this.tpm = tpm;
    }

    public BigDecimal getStandardAmount() {
        return standardAmount;
    }

    public void setStandardAmount(BigDecimal standardAmount) {
        this.standardAmount = standardAmount;
    }

    public FeeData extractFee(String entCode, String feeCode, String userCode, String passengerName){
        FeeData feeData = new FeeData();

        feeData.setEntCode(entCode);
        feeData.setFeeCode(feeCode);
        feeData.setUserCode(userCode);
        feeData.setComments("乘机人:" + passengerName);

        //默认设置费用类型为员工住宿类型
        feeData.setFeeTypeCode(Constant.DEFAULT_AIRFARE_FEE_TYPE);

        //消费金额
        //支付方式1 现金, 2 信用卡 ,3 支付宝, 4 借记卡, 5 其他
        //feeData.setPayMethod(PayType.fromDesc(payType));
        feeData.setConsumeAmount(totalAmount.add(serviceAmount));
        feeData.setConsumeCcy(Constant.DEFAULT_CTRIP_CURRENCY);
        //feeData.setConsumeTime(orderedAt);
        //feeData.setSourceId(orderId);
        feeData.setSourceType(FeeSourceType.CTRIP.getCode());
        feeData.setStatus(Constant.DEFAULT_FEE_STATUS);
        feeData.setFeeTypeGroupTags(FeeTypeGroupTag.Airfare);

        feeData.setBaseCcy(Constant.DEFAULT_CTRIP_CURRENCY);
        feeData.setExchangeRate(Constant.DEFAULT_EXCHANGE_RATE);
        feeData.setSysExchangeRate(Constant.DEFAULT_EXCHANGE_RATE);
        feeData.setFeeAmount(feeData.getConsumeAmount());
        feeData.setApprovedAmount(feeData.getConsumeAmount());

        feeData.setValid(true);
        return feeData;
    }


    public List<FeeDynamicField> extractFeeDynamicFields(String entCode, String feeCode) {
        List<FeeDynamicField> feeDynamicFields = new ArrayList<>();

        for(FeeDynamicFieldCode dynamicFieldCode:FeeDynamicFieldCode.getAirfareFieldCodes()){
            FeeDynamicField dynamicField = new FeeDynamicField();
            dynamicField.setEntCode(entCode);
            dynamicField.setFeeCode(feeCode);
            dynamicField.setFeeTypeCode(Constant.DEFAULT_AIRFARE_FEE_TYPE);
            dynamicField.setFeeKind(Constant.DEFAULT_FEE_KIND);
            dynamicField.setFeeDetailChooseCode(dynamicFieldCode.getCode());

            switch(dynamicFieldCode) {
                case AIRFARE_CONSUMPTION_PLATFORM:
                    dynamicField.setFeeDetailChooseValue(Constant.DEFAULT_CONSUMPTION_PLATFORM);
                    break;
                case AIRFARE_DEPARTURE_CITY:
                    dynamicField.setFeeDetailChooseValue(departureCityName);
                    break;
                case AIRFARE_ARRIVAL_CITY:
                    dynamicField.setFeeDetailChooseValue(arrivalCityName);
                    break;
                case AIRFARE_DEPARTURE_TIME:
                    dynamicField.setFeeDetailChooseValue(new DateTime(takeOffAt).toString(Constant.DATE_TIME_FORMAT));
                    break;
                case AIRFARE_ARRIVAL_TIME:
                    dynamicField.setFeeDetailChooseValue(new DateTime(arrivalAt).toString(Constant.DATE_TIME_FORMAT));
                    break;
                case AIRFARE_FLIGHT_NO:
                    dynamicField.setFeeDetailChooseValue(flightNo);
                    break;
                case AIRFARE_CLASS_NAME:
                    dynamicField.setFeeDetailChooseValue(className);
                    break;
            }

            feeDynamicFields.add(dynamicField);
        }

        return feeDynamicFields;
    }

}
